﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HSDc.RingleFlow.Api.Kernel;
using HSDc.RingleFlow.Kernel.ProcessActivity;

namespace HSDc.RingleFlow.Kernel
{
    class ProcessDefinition: IProcessDefinition
    {
        private string _id;
        private string _name;
        private string _version;
        private bool _active;
        private int _activeInstancesCount;
        private SortedDictionary<int, Activity> _activities = new SortedDictionary<int,Activity>();
        internal ProcessDefinition(string _id, string _name, string _version,
                                            bool _active, int _activeInstancesCount)
        {
            this._id = _id;
            this._name = _name;
            this._version = _version;
            this._active = _active;
            this._activeInstancesCount = _activeInstancesCount;
        }
        #region Interface Implementation
        string IProcessDefinition.Id
        {
            get { return _id; }
        }

        string IProcessDefinition.Name
        {
            get { return _name; }
        }

        string IProcessDefinition.Version
        {
            get { return _version; }
        }

        bool IProcessDefinition.Active
        {
            get { return _active; }
        }

        int IProcessDefinition.ActiveProcessInstances
        {
            get { return _activeInstancesCount; }
        }
        #endregion
        internal void AddActivity( Activity _activity)
        {
            _activities.Add((_activities.Count + 1), _activity);
        }

        internal Activity GetFirstActivity()
        {
            return _activities.Values.First();
        }

        internal List<Activity> NextActivities(string currentId, Dictionary<string, object> variables)
        {
            List<Activity> next = new List<Activity>();
            foreach (Activity act in _activities.Values)
            {
                if (act.Id.Equals(currentId))
                {
                    foreach (Transition trans in act.OutboundTransitions)
                    {
                        if (trans.CheckConstraints((act.Rule==null)?string.Empty:act.Rule.Execute(variables)))
                            next.Add(trans.Go());
                    }
                    break;
                }
            }
            return next;
        }

        internal Activity FindActivity(string id)
        {
            foreach (Activity act in _activities.Values)
                if (act.Id.Equals(id))
                    return act;
            return null;
        }
    }
}
